package cwinsor.com.leaf_raking;

import java.util.Arrays;
import java.util.List;

public final class WorkShift {

	/*
	 * properties
	 */
	private String name;
	private Day day;
	private StartTime startTime;

	/*
	 * getters
	 */
	public final String name() { return name; };
	public final Day day() { return day; };
	public final StartTime startTime() { return startTime; };

	/*
	 * private constructor
	 */
	private WorkShift(String name, Day day, StartTime startTime) {
		this.name = name;
		this.day = day;
		this.startTime = startTime;
	}

	/*
	 * global instances
	 */
	public static final WorkShift NOV_1_AM  = new WorkShift("Nov1_AM",  Day.NOV_1,  StartTime.T_8_30);
	public static final WorkShift NOV_1_PM  = new WorkShift("Nov1_PM",  Day.NOV_1,  StartTime.T_1_00);
	public static final WorkShift NOV_2_AM  = new WorkShift("Nov2_AM",  Day.NOV_2,  StartTime.T_8_30);
	public static final WorkShift NOV_2_PM  = new WorkShift("Nov2_PM",  Day.NOV_2,  StartTime.T_1_00);
	public static final WorkShift NOV_8_AM  = new WorkShift("Nov8_AM",  Day.NOV_8,  StartTime.T_8_30);
	public static final WorkShift NOV_8_PM  = new WorkShift("Nov8_PM",  Day.NOV_8,  StartTime.T_1_00);
	public static final WorkShift NOV_9_AM = new WorkShift("Nov9_AM", Day.NOV_9, StartTime.T_8_30);
	public static final WorkShift NOV_9_PM = new WorkShift("Nov9_PM", Day.NOV_9, StartTime.T_1_00);
	public static final WorkShift NOV_15_AM = new WorkShift("Nov15_AM", Day.NOV_15, StartTime.T_8_30);
	public static final WorkShift NOV_15_PM = new WorkShift("Nov15_PM", Day.NOV_15, StartTime.T_1_00);
	public static final WorkShift NOV_16_AM = new WorkShift("Nov16_AM", Day.NOV_16, StartTime.T_8_30);
	public static final WorkShift NOV_16_PM = new WorkShift("Nov16_PM", Day.NOV_16, StartTime.T_1_00);

	/*
	 * global instances as a list (public method)
	 */
	public static final List<WorkShift> asList() {
		return instanceList;		
	}

	/*
	 * instances list (private)
	 */
	private static final List<WorkShift> instanceList = Arrays.asList(
			NOV_1_AM,
			NOV_1_PM,
			NOV_2_AM,
			NOV_2_PM,
			NOV_8_AM,
			NOV_8_PM,
			NOV_9_AM,
			NOV_9_PM,
			NOV_15_AM,
			NOV_15_PM,
			NOV_16_AM,
			NOV_16_PM);

	/*
	 * number of instances
	 */
	public static final Integer size() { return instanceList.size(); };

	/*
	 * convert shift to an index
	 */
	public Integer toIndex() {
		if (this == NOV_1_AM) { return 0; }
		if (this == NOV_1_PM) { return 1; }
		if (this == NOV_2_AM) { return 2; }
		if (this == NOV_2_PM) { return 3; }
		if (this == NOV_8_AM) { return 4; }
		if (this == NOV_8_PM) { return 5; }
		if (this == NOV_9_AM) { return 6; }
		if (this == NOV_9_PM) { return 7; }
		if (this == NOV_15_AM) { return 8; }
		if (this == NOV_15_PM) { return 9; }
		if (this == NOV_16_AM) { return 10; }
		if (this == NOV_16_PM) { return 11; }
		Msg.fatal(dS + ": in toIndex - hit the default case");
		return null;		
	}

	public static WorkShift indexToShift(Integer i) {
		if (i.equals(0)) { return NOV_1_AM; }
		if (i.equals(1)) { return NOV_1_PM; }
		if (i.equals(2)) { return NOV_2_AM; }
		if (i.equals(3)) { return NOV_2_PM; }
		if (i.equals(4)) { return NOV_8_AM; }
		if (i.equals(5)) { return NOV_8_PM; }
		if (i.equals(6)) { return NOV_9_AM; }
		if (i.equals(7)) { return NOV_9_PM; }
		if (i.equals(8)) { return NOV_15_AM; }
		if (i.equals(9)) { return NOV_15_PM; }
		if (i.equals(10)) { return NOV_16_AM; }
		if (i.equals(11)) { return NOV_16_PM; }
		Msg.fatal(dS + ": in indexToShift - hit the default case");
		return null;	
	}


	/*
	 * convert shift to an AmPm
	 */
	public AmPm toAmPm() {
		if (this == NOV_1_AM) { return AmPm.AM; }
		if (this == NOV_1_PM) { return AmPm.PM; }
		if (this == NOV_2_AM) { return AmPm.AM; }
		if (this == NOV_2_PM) { return AmPm.PM; }
		if (this == NOV_8_AM) { return AmPm.AM; }
		if (this == NOV_8_PM) { return AmPm.PM; }
		if (this == NOV_9_AM) { return AmPm.AM; }
		if (this == NOV_9_PM) { return AmPm.PM; }
		if (this == NOV_15_AM) { return AmPm.AM; }
		if (this == NOV_15_PM) { return AmPm.PM; }
		if (this == NOV_16_AM) { return AmPm.AM; }
		if (this == NOV_16_PM) { return AmPm.PM; }
		Msg.fatal(dS + ": in toAmPm - hit the default case");
		return null;		
	}


	/*
	 * attempts to find a Shift in the given String
	 * if no matching Shift is found return null
	 * can be used if we want to specify a Shift with the customer notes
	 */
	public static final WorkShift stringContainsShift(String theString, boolean failIfNotFound) {

		// if the user sends a null string, but also has cleared failIfNotFound
		// then return a null back
		if ((theString == null) && (!failIfNotFound)) {
			return null;
		}

		for (WorkShift shift : WorkShift.asList())
			for (AmPm amPm : AmPm.asList()) {
				if (theString.contains(shift.name()) && theString.contains(amPm.name())) {
					return shift;
				}
			}
		// default
		if (failIfNotFound) {
			System.out.println(dS + "in stringContainsDay - cannot convert "
					+ theString 
					+ " to a Day");
			System.exit(1);
		}
		return null;
	}


	// debug
	private static String dS = "Shift";

	/*
	 * return a WorkShift
	 * given Day, StartTime
	 */
	public static WorkShift fromDayStartTime(Day day, StartTime startTime) {

		AmPm amPm = startTime.toAmPm();
		WorkShift temp = fromDayAmPm(day, amPm);
		return temp;
	}

	/*
	 * return a Workshift
	 * given Day, AmPm
	 */
	public static WorkShift fromDayAmPm(Day day, AmPm amPm) {
		if (day.equals(Day.NOV_1)  && (amPm.equals(AmPm.AM))) { return NOV_1_AM; }
		if (day.equals(Day.NOV_1)  && (amPm.equals(AmPm.PM))) { return NOV_1_PM; }
		if (day.equals(Day.NOV_2)  && (amPm.equals(AmPm.AM))) { return NOV_2_AM; }
		if (day.equals(Day.NOV_2)  && (amPm.equals(AmPm.PM))) { return NOV_2_PM; }
		if (day.equals(Day.NOV_8)  && (amPm.equals(AmPm.AM))) { return NOV_8_AM; }
		if (day.equals(Day.NOV_8)  && (amPm.equals(AmPm.PM))) { return NOV_8_PM; }
		if (day.equals(Day.NOV_9)  && (amPm.equals(AmPm.AM))) { return NOV_9_AM; }
		if (day.equals(Day.NOV_9)  && (amPm.equals(AmPm.PM))) { return NOV_9_PM; }
		if (day.equals(Day.NOV_15) && (amPm.equals(AmPm.AM))) { return NOV_15_AM; }
		if (day.equals(Day.NOV_15) && (amPm.equals(AmPm.PM))) { return NOV_15_PM; }
		if (day.equals(Day.NOV_16) && (amPm.equals(AmPm.AM))) { return NOV_16_AM; }
		if (day.equals(Day.NOV_16) && (amPm.equals(AmPm.PM))) { return NOV_16_PM; }

		// not found
		Msg.fatal(dS + ": unable to convert Day " + day.name() + " AmPm " + amPm.name() + " to a WorkShift");
		return null;
	}
}